package com.whcoding.test.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.whcoding.test.common.api.CommonResult;
import com.whcoding.test.pojo.MinioUploadVO;
import com.whcoding.test.pojo.OssDataVO;
import io.minio.MinioClient;
import io.minio.policy.PolicyType;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;


/**
 * <p>
 * 文件上传 Controller
 * </p>
 *
 * @author: whcoding
 * @create: 2022-03-01 15:09
 */
@RestController
@Slf4j
@RequestMapping("/upload")
public class UploadController {

	@Value("${spring.servlet.multipart.location}")
	private String fileTempPath;
	@Value("${oss.endpoint}")
	private String ENDPOINT;
	@Value("${oss.bucketname}")
	private String BUCKET_NAME;
	@Value("${oss.keyid}")
	private String ACCESS_KEY;
	@Value("${oss.keysecret}")
	private String SECRET_KEY;

	private static final Logger LOGGER = LoggerFactory.getLogger(UploadController.class);

	/**
	 * OSS 上传文件
	 *
	 * @param file
	 * @return
	 */
	@RequestMapping(value = "/ossUpload", method = RequestMethod.POST)
	@ResponseBody
	public CommonResult ossUpload(@RequestParam("file") MultipartFile file) {
		try {
			//创建一个MinIO的Java客户端
			MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
			boolean isExist = minioClient.bucketExists(BUCKET_NAME);
			if (isExist) {
				LOGGER.info("存储桶已经存在！");
			} else {
				//创建存储桶并设置只读权限
				minioClient.makeBucket(BUCKET_NAME);
				minioClient.setBucketPolicy(BUCKET_NAME, "*.*", PolicyType.READ_ONLY);
			}
			String filename = file.getOriginalFilename();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			// 设置存储对象名称
			String objectName = sdf.format(new Date()) + "/" + filename;
			// 使用putObject上传一个文件到存储桶中
			minioClient.putObject(BUCKET_NAME, objectName, file.getInputStream(), file.getContentType());
			LOGGER.info("文件上传成功!");
			MinioUploadVO minioUploadDto = new MinioUploadVO();
			minioUploadDto.setName(filename);
			minioUploadDto.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + objectName);
			return CommonResult.success(minioUploadDto);
		} catch (Exception e) {
			LOGGER.info("上传发生错误: {}！", e.getMessage());
		}
		return CommonResult.failed();
	}

	/**
	 * OSS 删除数据
	 *
	 * @param objectName 文件名称
	 * @return
	 */
	@RequestMapping(value = "/ossDelete", method = RequestMethod.POST)
	@ResponseBody
	public CommonResult ossDelete(@RequestParam("objectName") String objectName) {
		try {
			MinioClient minioClient = new MinioClient(ENDPOINT, ACCESS_KEY, SECRET_KEY);
			minioClient.removeObject(BUCKET_NAME, objectName);
			return CommonResult.success(null);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return CommonResult.failed();
	}


	/**
	 * http://localhost:9180/demo/upload/local
	 *
	 * @param file
	 * @return
	 */
	@PostMapping(value = "/local", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
	public Dict local(@RequestParam("file") MultipartFile file) {
		if (file.isEmpty()) {
			return Dict.create().set("code", 400).set("message", "文件内容为空");
		}
		String fileName = file.getOriginalFilename();
		String rawFileName = StrUtil.subBefore(fileName, ".", true);
		String fileType = StrUtil.subAfter(fileName, ".", true);
		String localFilePath = StrUtil.appendIfMissing(fileTempPath, "/") + rawFileName + "-" + DateUtil.current(false) + "." + fileType;
		try {
			file.transferTo(new File(localFilePath));
		} catch (IOException e) {
			log.error("【文件上传至本地】失败，绝对路径：{}", localFilePath);
			return Dict.create().set("code", 500).set("message", "文件上传失败");
		}
		log.info("【文件上传至本地】绝对路径：{}", localFilePath);
		return Dict.create().set("code", 200).set("message", "上传成功").set("data", Dict.create().set("fileName", fileName).set("filePath", localFilePath));
	}

	/**
	 * 上传多个文件
	 *
	 * @param uploadFile
	 * @return
	 */
	@PostMapping(value = "/uploadFileMore")
	public ResponseEntity uploadFileMore(@RequestParam("uploadFile") MultipartFile[] uploadFile) {

		if (uploadFile == null || uploadFile.length == 0) {
			return ResponseEntity.ok("没有获取到文件！");
		}
		//循环获取file数组中得文件
		File pfile = new File("F:/my/fileupload/");
		if (!pfile.exists()) {
			pfile.mkdirs();
		}
		for (int i = 0; i < uploadFile.length; i++) {
			MultipartFile file = uploadFile[i];
			//保存文件
			if (!file.isEmpty()) {
				try {
					//转存文件  file.getOriginalFilename();文件原名称包括后缀名
					file.transferTo(new File(pfile, file.getOriginalFilename()));
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return ResponseEntity.ok("成功");
	}


	@PostMapping(value = "/uploadFileOne")
	public ResponseEntity uploadFileOne(@RequestParam("uploadFile") MultipartFile uploadFile) throws IOException {
		if (null == uploadFile) {
			return ResponseEntity.ok("上传失败，无法找到文件！");
		}
		InputStream stream = uploadFile.getInputStream();
		// 1.BMP、JPG、JPEG、PNG、GIF
		String fileName = uploadFile.getOriginalFilename().toLowerCase();
		if (!fileName.endsWith(".bmp") && !fileName.endsWith(".jpg")
				&& !fileName.endsWith(".jpeg") && !fileName.endsWith(".png")
				&& !fileName.endsWith(".gif")
				&& !fileName.endsWith(".txt")) {
			return ResponseEntity.ok("上传失败，请选择BMP、JPG、JPEG、PNG、GIF文件！");
		}
		//存储路径可在配置文件中指定
		File pfile = new File("F:/my/fileupload/");
		if (!pfile.exists()) {
			pfile.mkdirs();
		}
		try {
			// 转存文件
			uploadFile.transferTo(new File(pfile, fileName));
		} catch (IOException e) {
			e.printStackTrace();
			return ResponseEntity.ok("上传失败");
		}
		//逻辑处理
		return ResponseEntity.ok("成功");
	}
}
